package com.zreal.generator.codegenerate.generate;

import com.zreal.generator.codegenerate.database.Column;
import com.zreal.generator.codegenerate.database.ReadTable;
import com.zreal.generator.codegenerate.database.Table;
import com.zreal.generator.codegenerate.database.TableConvert;
import com.zreal.generator.config.CodeProperties;
import com.zreal.generator.config.PropertiesBuilder;
import com.zreal.generator.util.Constants;
import com.zreal.generator.util.StringUtils;

import java.io.File;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CodeGenerate {

    private CodeProperties codeProperties = PropertiesBuilder.build();

    public String getOutFilePath(String templatePath) {
        String outFilePath = "";
        String basePath = codeProperties.getTargetPath().replace("/", Constants.FILE_SEPARATOR).replace("\\", Constants.FILE_SEPARATOR)
                + Constants.FILE_SEPARATOR + codeProperties.getPackageName().replace(".", Constants.FILE_SEPARATOR);
        String fileSuffix = templatePath.substring(templatePath.lastIndexOf(Constants.FILE_SEPARATOR)+1, templatePath.lastIndexOf("."));
        templatePath = templatePath.toLowerCase();
        String[] packages = {"entity","service","controller","sqlmapper","mapper"};
        for (int i = 0; i < packages.length; i++) {
            if (templatePath.contains(packages[i])) {
                outFilePath = basePath + Constants.FILE_SEPARATOR + packages[i] + Constants.FILE_SEPARATOR + "{0}" + fileSuffix;
                if("sqlmapper".equals(packages[i])){
                    outFilePath += ".xml";
                }else{
                    outFilePath += ".java";
                }
                break;
            }
        }
        if(StringUtils.isEmpty(outFilePath)){
            outFilePath = basePath + Constants.FILE_SEPARATOR + "{0}" + fileSuffix;
        }

        return outFilePath;
    }

    /**
     * 获取模板文件
     *
     * @return
     */
    private List<File> getTemplates() {
        String templateDir = codeProperties.getTemplateDir();
        List<String> templateFiles = codeProperties.getTemplateFiles();
        List<File> templates = new ArrayList<>();
        for (int i = 0; i < templateFiles.size(); i++) {
            String fileName = templateFiles.get(i);
            URL fileUrl = Thread.currentThread().getContextClassLoader().getResource("templates/" + templateDir + "/" + fileName);
            if(fileUrl == null){
                System.err.println("未找到模板文件:templates/" + templateDir + "/" + fileName);
                continue;
            }
            File templateFile = new File(fileUrl.getPath());
            templates.add(templateFile);
        }
        return templates;
    }

    public void generate() {
        CodeFactory factory = new CodeFactory();
        List<File> templates = getTemplates();
        List<Table> tableList = getTables();
        for (Table t : tableList) {
            System.out.println(t);
            for (File template : templates) {
                String templateName = template.getName();
                String outFilePath = getOutFilePath(template.getPath());
                outFilePath = MessageFormat.format(outFilePath,t.getClassName());
                Map<String, Object> data = new HashMap<>();
                data.put("table", t);
                data.put("packageName", codeProperties.getPackageName());
                try {
                    factory.outputFile(template, outFilePath, data);
                    System.out.println("生成" + template.getName() + "成功:" + outFilePath);
                } catch (Exception e) {
                    System.err.println("生成" + templateName + "失败:" + outFilePath);
                    e.printStackTrace();
                }
            }
        }

    }


    /**
     * 获取表数据
     *
     * @return
     */
    private List<Table> getTables() {
        String[] tables = codeProperties.getTableName().split(",");
        List<Table> tableList = new ArrayList<>();
        for (String table : tables) {
            //多张表的字段
            List<Column> list = ReadTable.readTableColumn(table);
            Map<String, Table> map = new HashMap<>();
            if (list.size() > 0) {
                for (Column col : list) {
                    String tableName = col.getTableName().toUpperCase();
                    Table t = map.get(tableName);
                    if (t == null) {
                        t = new Table();
                        t.setColumns(new ArrayList<>());
                        if (col.isPrimaryKey()) {
                            t.setPrimaryKey(col.getFieldName());
                        }
                        map.put(tableName, t);
                    }
                    t.getColumns().add(col);
                }
                for (String tableName : map.keySet()) {
                    Table t = map.get(tableName);
                    String tableStr = tableName.toLowerCase();
                    if (!StringUtils.isEmpty(codeProperties.getIgnoreTablePrefix())) {
                        String prefix = codeProperties.getIgnoreTablePrefix().toLowerCase();
                        if (tableStr.contains(prefix)) {
                            tableStr = tableStr.substring(tableStr.indexOf(prefix) + prefix.length());
                        }
                    }
                    t.setClassName(TableConvert.formatTableName(tableStr));
                    t.setTableName(tableName);
                    tableList.add(t);
                }
            } else {
                throw new RuntimeException(Constants.ERROR_TITLE + "\n" + Constants.ERROR_MSG_NOTABLE);
            }

        }
        return tableList;
    }


}
